package com.jymj.common.aop;

import com.alibaba.fastjson.JSONObject;
import com.jymj.common.annotation.CacheFind;
import com.jymj.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author Lzh
 * @date 2020/12/17 15:37
 */
@Component
@Aspect
@Slf4j
public class CacheAOP {
    /**
     * 拦截@CacheFind注解标识的方法.
     * 通知选择: 缓存的实现应该选用环绕通知
     * 步骤:
     *  1.动态生成key  用户填写的key+用户提交的参数
     */
    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){
        RedisUtils redisUtils = new RedisUtils();
        //获取注解内容
        String key = cacheFind.key();
        //拼接参数
        Object[] args = joinPoint.getArgs();
        key=key+"::"+ Arrays.toString(args);
        //从redis中获取数据
        Object result = null;
        if (redisUtils.exist(key)){
            String json = redisUtils.get(key);
            //获取返回值类型
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Class returnType = methodSignature.getReturnType();
            result = JSONObject.parseObject(json, returnType);
            log.info("查询缓存完成");
        }else {//key不存在
            try {
                result = joinPoint.proceed();//执行目标方法获取返回值
                String json = JSONObject.toJSONString(result);
                if (cacheFind.seconds()>0){
                    redisUtils.setex(key, cacheFind.seconds(), json);
                }else{
                    redisUtils.set(key, json);
                }
                log.info("执行数据库查询操作，保存数据到redis");
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                throw new RuntimeException(throwable);
            }
        }
        return result;
    }



}
